﻿
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace std;
int main() {
	string a;//输入字符串
	char s[30];//代表储存运算符号的栈
	int top = -1;
	cin>>(a);
	int i;
	int flag = 0;//标记，看是不是第一个数字，是直接打出，不是先打出空格
	for (i = 0; a[i]; i++) {
		if (a[i] >= '0' && a[i] <= '9') {//如果是数字，直接打印出数字，包括多位的数字和小数
			int j = i;//保存开头
			while ((a[i] >= '0' && a[i] <= '9') || a[i] == '.')i++;//找到第一个不为数字的字符
			i--;//回到最后一个数字字符上，因为for循环最后i++；
			int k;
			if (!flag || (a[j - 1] == '-' && (a[j - 2] == '(' || a[j - 2] == '+' || a[j - 2] == '-' || a[j - 2] == '*' || a[j - 2] == '/')) || (a[j - 1] == '-' && j - 1 == 0) || (a[j - 1] == '+' && j - 1 == 0) || (a[j - 1] == '+' && (a[j - 2] == '(' || a[j - 2] == '+' || a[j - 2] == '-' || a[j - 2] == '*' || a[j - 2] == '/')));//负数或者第一个数字，数字前不打空格，否则会和负号分开
			else printf(" ");//这里是j千万别写成i，j记录的数字的开头
			flag = 1;
			for (k = j; k <= i; k++)printf("%c", a[k]);//输出
		}
		else {//如果是运算符
			if (i == 0 && (a[i] == '-' || a[i] == '+')) {//开始的符号
				if (a[i] == '-')printf("%c", a[i]);
				continue;
			}
			if (i == 1 && a[i - 1] == '(' && (a[i] == '-' || a[i] == '+')) {//如果第一个是括号然后又是正负，坑死了这里，打死没想到
				if (a[i] == '-')printf("%c", a[i]);
				continue;
			}
			if (top == -1) {//如果栈为空，直接把运算符加进去
				s[++top] = a[i];
			}
			else {//入队原则：如果当前符号比栈顶优先级大，入栈，否则pop输出栈顶，再继续比较，直到比栈顶优先级大再入栈
				if (a[i] == '+' || a[i] == '-') {//如果是加减号
					if (a[i] == '-' && a[i - 1] == '(') {//中间的负号
						printf(" -");
						continue;
					}
					if (a[i] == '+' && a[i - 1] == '(') {//中加的加号
						printf(" ");//如果有正号，不输出
						continue;
					}
					if ((a[i] == '+' || a[i] == '-') && (a[i - 1] == '+' || a[i - 1] == '-' || a[i - 1] == '*' || a[i - 1] == '/')) {
						if (a[i] == '-')printf(" %c", a[i]);
						if (a[i] == '+')printf(" ");//正号不输出
						continue;
					}
					//if(s[top]=='*'||s[top]=='/'){//首先比较时第一个一定要比当前优先级大才开始出队。否则只能入队
					while ((top != -1) && (s[top] == '+' || s[top] == '-' || s[top] == '/' || s[top] == '*')) {//比较如果栈内元素优先级大于当前符号。先出栈，直到比它大
						printf(" %c", s[top--]);
					}
					//}
					s[++top] = a[i];//判断并出栈之后这个符号就可以入栈了
				}
				else if (a[i] == '*' || a[i] == '/') {//如果是乘除号
					while ((top != -1) && (s[top] == '*' || s[top] == '/')) {//因为乘除号是最高优先级，所以只有相等时需要出栈
						printf(" %c", s[top--]);
					}
					s[++top] = a[i];
				}
				else if (a[i] == '(') {//左括号的时候比较特殊，直接入栈
					s[++top] = a[i];
				}
				else if (a[i] == ')') {//右括号的时候直接出栈到左括号
					while ((top != -1) && s[top] != '(')
						printf(" %c", s[top--]);
					top--;//把左括号pop掉
				}
			}
		}
	}
	//结束后栈内剩下的符号一次出栈输出即可
	while (top != -1) {
		printf(" %c", s[top--]);
	}
	return 0;
}



